<script>
  import { Body, ModalContent, Layout, notifications } from "@budibase/bbui"
  import { datasources as datasourcesStore } from "stores/builder"
  import ICONS from "components/backend/DatasourceNavigator/icons"
  import { IntegrationNames } from "constants"
  import { createEventDispatcher, onMount } from "svelte"
  import TableOrViewOption from "./TableOrViewOption.svelte"
  import * as format from "helpers/data/format"

  export let onConfirm
  export let selectedTablesAndViews

  const dispatch = createEventDispatcher()

  const getViews = table => {
    const views = Object.values(table.views || {}).filter(
      view => view.version === 2
    )

    return views.map(view => ({
      icon: "Remove",
      name: view.name,
      id: view.id,
      tableSelectFormat: format.tableSelect.viewV2(view),
      datasourceSelectFormat: format.datasourceSelect.viewV2(view),
    }))
  }

  const getTablesAndViews = datasource => {
    let tablesAndViews = []
    const tables = Array.isArray(datasource.entities)
      ? datasource.entities
      : Object.values(datasource.entities ?? {})

    for (const table of tables) {
      if (table._id === "ta_users") {
        continue
      }

      const formattedTable = {
        icon: "Table",
        name: table.name,
        id: table._id,
        tableSelectFormat: format.tableSelect.table(table),
        datasourceSelectFormat: format.datasourceSelect.table(
          table,
          $datasourcesStore.list
        ),
      }

      tablesAndViews = tablesAndViews.concat([
        formattedTable,
        ...getViews(table),
      ])
    }

    return tablesAndViews
  }

  const getDatasources = rawDatasources => {
    const datasources = []

    for (const rawDatasource of rawDatasources) {
      if (
        rawDatasource.source === IntegrationNames.REST ||
        !rawDatasource["entities"]
      ) {
        continue
      }

      const datasource = {
        name: rawDatasource.name,
        iconComponent: ICONS[rawDatasource.source],
        tablesAndViews: getTablesAndViews(rawDatasource),
      }

      datasources.push(datasource)
    }

    return datasources
  }

  $: datasources = getDatasources($datasourcesStore.list)

  const toggleSelection = tableOrView => {
    dispatch("toggle", tableOrView)
  }

  onMount(async () => {
    try {
      await datasourcesStore.fetch()
    } catch (error) {
      notifications.error("Error fetching datasources")
    }
  })
</script>

<ModalContent
  title="Autogenerated screens"
  confirmText="Next"
  cancelText="Cancel"
  {onConfirm}
  disabled={!selectedTablesAndViews.length}
  size="L"
>
  <Body size="S">
    Select which datasources you would like to use to create your screens
  </Body>
  <Layout noPadding gap="S">
    {#each datasources as datasource}
      <div class="datasource">
        <div class="header">
          <svelte:component
            this={datasource.iconComponent}
            height="18"
            width="18"
          />
          <h2>{datasource.name}</h2>
        </div>
        <!-- List all tables -->
        {#each datasource.tablesAndViews as tableOrView}
          {@const selected = selectedTablesAndViews.some(
            selected => selected.id === tableOrView.id
          )}
          <TableOrViewOption
            on:click={() => toggleSelection(tableOrView)}
            {selected}
            {tableOrView}
          />
        {/each}
      </div>
    {/each}
  </Layout>
</ModalContent>

<style>
  .datasource {
    padding-bottom: 15px;
    display: flex;
    flex-direction: column;
    grid-gap: var(--spacing-s);
    max-width: 100%;
    min-width: 0;
  }

  .datasource:last-child {
    padding-bottom: 0;
  }

  .header {
    display: flex;
    align-items: center;
    padding-bottom: var(--spacing-m);
  }

  .header :global(svg) {
    flex-shrink: 0;
  }

  .header h2 {
    padding-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 14px;
    font-weight: 400;
    margin: 0;
    margin-left: 10px;
  }
</style>
